package android.slc.box.core.launcher;

import android.slc.box.core.scope.StageScope;
import android.slc.box.core.virtual_android.Bundle;
import cn.hutool.core.util.ArrayUtil;
import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.Scope;
import de.saxsys.mvvmfx.ViewModel;
import de.saxsys.mvvmfx.ViewTuple;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.Window;

import java.util.Collection;
import java.util.List;

public class EmbeddedWindowLauncherImpl extends WindowLauncherImpl<Window> implements EmbeddedWindowLauncher {
    private FxmlView<?> lastView;
    private ViewModel lastViewModel;
    private Scope windowScope;

    public EmbeddedWindowLauncherImpl(Scope windowScope, List<String> stylesheets, Bundle bundle) {
        this(getWindowByScope(windowScope), stylesheets, bundle);
        this.windowScope = windowScope;
    }

    private static Window getWindowByScope(Scope windowScope) {
        /*if (windowScope instanceof EmbeddedWindowScope) {
            return ((EmbeddedWindowScope) windowScope).getCurrentStage();
        } else if (windowScope instanceof StageScope) {
            return ((StageScope) windowScope).getCurrentStage();
        }*/
        if (windowScope instanceof StageScope) {
            return ((StageScope) windowScope).getCurrentStage();
        }
        return null;
    }

    public EmbeddedWindowLauncherImpl(Window currentStage, List<String> stylesheets, Bundle bundle) {
        super(currentStage, stylesheets, bundle);
    }

    private void applyStyle(Scene scene) {
        if (getStylesheets() != null) {
            scene.getStylesheets().addAll(getStylesheets());
        }
    }

    @Override
    public void switchScene(Scene scene) {
        applyStyle(scene);
        /*if (requireWindow() instanceof EmbeddedWindow) {
            ((EmbeddedWindow) requireWindow()).setScene(scene);
        } else if (requireWindow() instanceof Stage) {
            ((Stage) requireWindow()).setScene(scene);
        }*/
        if (requireWindow() instanceof Stage) {
            ((Stage) requireWindow()).setScene(scene);
        }
    }

    @Override
    public <ViewType extends FxmlView<? extends ViewModelType>, ViewModelType extends ViewModel> void switchView(Class<ViewType> viewClass, Bundle bundle, Scope... scopes) {
        Scope[] scopeArray = scopes;
        if (this.windowScope != null) {
            scopeArray = ArrayUtil.append(scopes, windowScope);
        }
        Parent view = createView(viewClass, bundle, scopeArray);
        switchView(view);
    }

    @Override
    public <ViewType extends FxmlView<? extends ViewModelType>, ViewModelType extends ViewModel> void addView(Pane parentPane, Class<ViewType> viewClass, Bundle bundle, Scope... scopes) {
        Scope[] scopeArray = scopes;
        if (this.windowScope != null) {
            scopeArray = ArrayUtil.append(scopes, windowScope);
        }
        Parent view = createView(viewClass, bundle, scopeArray);
        addView(parentPane, view);
    }

    @Override
    public void launcherWindow(Window targetWindow, Scene scene) {
        applyStyle(scene);
        /*if (requireWindow() instanceof EmbeddedWindow) {
            ((EmbeddedWindow) requireWindow()).setScene(scene);
            ((EmbeddedWindow) requireWindow()).show();
        } else if (requireWindow() instanceof Stage) {
            ((Stage) requireWindow()).setScene(scene);
            ((Stage) requireWindow()).show();
        }*/
        if (requireWindow() instanceof Stage) {
            ((Stage) requireWindow()).setScene(scene);
            ((Stage) requireWindow()).show();
        }
    }

    @Override
    public <ViewType extends FxmlView<? extends ViewModelType>, ViewModelType extends ViewModel> ViewTuple<ViewType, ViewModelType> createViewTuple(Class<ViewType> viewClass, Collection<Scope> scopes) {
        ViewTuple<ViewType, ViewModelType> viewTuple = super.createViewTuple(viewClass, scopes);
        this.lastView = viewTuple.getCodeBehind();
        this.lastViewModel = viewTuple.getViewModel();
        return viewTuple;
    }

    public <ViewType extends FxmlView<? extends ViewModelType>, ViewModelType extends ViewModel> ViewType getLastCreateView() {
        return (ViewType) lastView;
    }

    public <ViewModelType extends ViewModel> ViewModelType getLastCreateVm() {
        return (ViewModelType) lastViewModel;
    }

}
